package org.wattdepot.cli;

import java.util.HashMap;
import java.util.Scanner;
import org.wattdepot.cli.commands.CarbonContent;
import org.wattdepot.cli.commands.ChartPower;
import org.wattdepot.cli.commands.FuelTypes;
import org.wattdepot.cli.commands.HelpCommand;
import org.wattdepot.cli.commands.ListPowerDay;
import org.wattdepot.cli.commands.ListPowerTimeStamp;
import org.wattdepot.cli.commands.ListSensorDay;
import org.wattdepot.cli.commands.ListSensorTimestamp;
import org.wattdepot.cli.commands.ListSources;
import org.wattdepot.cli.commands.ListSummary;
import org.wattdepot.cli.commands.ListTotalGenerated;
import org.wattdepot.cli.commands.TotalPowerFuelType;
import org.wattdepot.cli.commands.UserCommands;
import org.wattdepot.client.WattDepotClientException;

/**
 * Provides the commands for the user interface for the wattdepot-cli program.
 * 
 * @author Jarret Mizo, Shaun Ramento
 * 
 */
public class UserCommandInterface extends CommandLineInterface {
  /** Used string to check generated. */
  public static final String GENERATED = "generated";
  /** Used to check consumed. */
  public static final String CONSUMED = "consumed";

  /**
   * Starts the command prompt.
   * 
   * @throws WattDepotClientException Exceptions that is thrown
   */
  public void startUserInterface() throws WattDepotClientException {

    HashMap<String, UserCommands> commandMap = new HashMap<String, UserCommands>();
    commandMap.put("help", new HelpCommand());
    commandMap.put("sources", new ListSources());
    commandMap.put("summary", new ListSummary());
    commandMap.put("sensordatatimestamp", new ListSensorTimestamp());
    commandMap.put("dailysensordataday", new ListSensorDay());
    commandMap.put("powertimestamp", new ListPowerTimeStamp());
    commandMap.put("powerstatsdaysampling-intervalstatistic", new ListPowerDay());
    commandMap.put("totalgenerateddaysampling-interval", new ListTotalGenerated());
    commandMap.put("chartpowersampling-intervalfile", new ChartPower());
    commandMap.put("fueltypes", new FuelTypes());
    commandMap.put("totalpowerfueltype", new TotalPowerFuelType());
    commandMap.put("carboncontentsampling-interval", new CarbonContent());

    if (getClient().isHealthy()) {
      // Indicate successful connection.
      System.out.println("Connected to " + getClient().getWattDepotUri());
    }

    // command prompt loop
    while (true) {
      // command prompt
      System.out.print(">");
      // retrieves input from keyboard
      Scanner scanner = new Scanner(System.in);
      // gets the input from keyboard
      String input = scanner.nextLine();
      String command = getInputKeywords(input);
      UserCommands userCommand = commandMap.get(command);
      // breaks loop if input is quit
      if (input.equalsIgnoreCase("quit")) {
        break;
      }

      if (userCommand == null) {
        System.out.println("Invalid Command, type \'help\' for list of commands.");
      }
      else {
        System.out.print(userCommand.doCommand(input));
      }

    }

  } // end startUserInterface method

  /**
   * Checks if source exists.
   * 
   * @param sourceName is the name of the source user is looking up.
   * @return True if source exists, false if error is thrown.
   */
  public boolean sourceExists(String sourceName) {
    try {
      getClient().getSource(sourceName);
      return true;
    }
    catch (WattDepotClientException exception) {
      // System.out.println("Source \"" + sourceName + "\" does not exist");
      return false;
    }
  }

  /**
   * Verifies if the extension is html.
   * 
   * @param html is the file extension
   * @return true if it is html else it is false
   */
  public boolean htmlValidation(String html) {
    int htmlExtension = html.length();
    String htmlValid = html.substring(htmlExtension - 4, htmlExtension);
    if (htmlValid.equalsIgnoreCase("html")) {

      return true;
    }
    return false;
  }

  /**
   * Returns the keywords of the inputed command.
   * 
   * @param input is the input from the user.
   * @return a string of keywords of the inputed command.
   */
  public String getInputKeywords(String input) {
    String command = null;
    String samplingInterval = "sampling-interval";

    // breaks up the input into an array to allow for checks
    String[] inputString = input.split(" ");
    int numberOfInputs = inputString.length;

    // checks if input is help
    if (input.equalsIgnoreCase("help")) {
      command = "help";
    }

    // checks if input is quit
    if (input.equalsIgnoreCase("quit")) {
      command = "quit";
    }

    // 2.3 sources
    if (input.equalsIgnoreCase("sources")) {
      command = "sources";
    }

    // 2.4 summary {source}
    if (numberOfInputs == 2 && inputString[0].equalsIgnoreCase("summary")) {
      command = "summary";
    }

    // 2.5 sensordata {source} timestamp {timestamp}
    if (numberOfInputs == 4 && inputString[0].equalsIgnoreCase("sensordata")
        && inputString[2].equalsIgnoreCase("timestamp")) {
      command = "sensordatatimestamp";
    }

    // 2.6 dailysensordata {source} day {day}
    if (numberOfInputs == 4 && inputString[0].equalsIgnoreCase("dailysensordata")
        && inputString[2].equalsIgnoreCase("day")) {
      command = "dailysensordataday";
    }

    // 2.7 power [generated|consumed] {source} timestamp {timestamp}
    if (numberOfInputs == 5 && inputString[0].equalsIgnoreCase("power")
        && inputString[3].equalsIgnoreCase("timestamp")) {
      command = "powertimestamp";
    }

    // 2.8 powerstats [generated|consumed] {source} day {day} sampling-interval {minutes} statistic
    // {max|min|average}
    if (numberOfInputs == 9 && inputString[0].equalsIgnoreCase("powerstats")
        && inputString[3].equalsIgnoreCase("day")
        && inputString[5].equalsIgnoreCase(samplingInterval)
        && inputString[7].equalsIgnoreCase("statistic")) {
      command = "powerstatsdaysampling-intervalstatistic";
    } // end if

    // 2.9 total [carbon|energy] generated {source} day {day} sampling-interval {minutes}
    if (numberOfInputs == 8 && inputString[0].equalsIgnoreCase("total")
        && inputString[2].equalsIgnoreCase("generated") && inputString[4].equalsIgnoreCase("day")
        && inputString[6].equalsIgnoreCase(samplingInterval)) {
      command = "totalgenerateddaysampling-interval";
    }

    // 2.10 chart power [generated|consumed] {source} {startday} {endday} sampling-interval
    // {minutes} file {file}
    if (numberOfInputs == 10 && inputString[0].equalsIgnoreCase("chart")
        && inputString[1].equalsIgnoreCase("power")
        && inputString[6].equalsIgnoreCase(samplingInterval)
        && inputString[8].equalsIgnoreCase("file")) {
      command = "chartpowersampling-intervalfile";
    }

    // 2.11 fueltypes {source}
    if (numberOfInputs == 2 && inputString[0].equalsIgnoreCase("fueltypes")) {
      command = "fueltypes";
    }
    //
    // 2.12 totalpower {source} {timestamp} fuelType {fueltype}
    if (numberOfInputs == 5 && inputString[0].equalsIgnoreCase("totalpower")
        && inputString[3].equalsIgnoreCase("fuelType")) {
      command = "totalpowerfueltype";
    }

    // 2.13 carboncontent {source} {timestamp} sampling-interval {interval}
    if (numberOfInputs == 5 && inputString[0].equalsIgnoreCase("carboncontent")
        && inputString[3].equalsIgnoreCase(samplingInterval)) {
      command = "carboncontentsampling-interval";
    }

    return command;
  }
}
